home *** CD-ROM | disk | FTP | other *** search
Text File | 1986-04-19 | 8.4 KB | 320 lines | [TEXT/MACA] |
- /* ----------------- crabs -----------------
- *
- * Implementation of the crabs game for the
- * Macintosh, written in Aztec C.
- * See Scientific American, Sep 1985, p18-23.
- *
- * Author: Fons Rademakers, Nikhef-h/CERN
- * Version: 29-oct-1985
- * Revision:
- *
- */
-
- #asm
- main
- dc.w $6400 ;ctl-enable, need time and locked in mem.
- dc.w 0 ;update as often as possible
- dc.w $0001 ;don't react on any specific event
- dc.w 0 ;no menu
-
- dc.w open_-main ;open routine
- dc.w nop_-main ;prime routine
- dc.w control_-main ;control routine
- dc.w nop_-main ;status routine
- dc.w close_-main ;close routine
-
- title_
- dc.b 8
- dc.b "Crabs "
- ds 0 ;for alignment
-
- public _Uend_,_Dorg_,_Cend_
-
- save_
- lea main+(_Uend_-_Dorg_)+(_Cend_-main),a4 ;set up globals
- move.l a0,Pbp_ ;save pb pointer
- move.l a1,Dp_ ;save DCE pointer
- rts
-
- restore_
- move.l Pbp_,a0
- rts
- #endasm
-
- #define _DRIVER
- #define SMALL_MEM
- #include <quickdraw.h>
- #include <memory.h>
- #undef SMALL_MEM
- #include <event.h>
- #include <pb.h>
- #include <desk.h>
-
- #define NULL (0L)
-
- #define BASE1 512 /* Mac screen size in x direction */
- #define BASE2 342 /* Mac screen size in y direction */
-
- #define MAXVEL 8 /* max velocity of the crabs */
- #define CRABS 10 /* # of crabs */
-
- #define SP (*(struct storage **)Dp->dCtlStorage)
-
- DCEPtr Dp;
- ParmBlkPtr Pbp;
-
- Rect wind_rect = {0, 0, 0, 0};
-
- struct storage {
- BitMap crabmap[4]; /* the 4 crab bitmaps */
- GrafPtr crabport; /* the crabs grafport */
- Pattern gray; /* backgr fill pattern */
- short crabspace[4][16]; /* space for the 4 crab bitmaps */
- short portspace[54]; /* space for the crabport */
- short xvel[CRABS], yvel[CRABS]; /* the crabs velocity */
- short newdest[CRABS][2], olddest[CRABS][2]; /* the crabs pos. */
- short olddir[CRABS]; /* the direction the crab was going
- */
- Boolean oldbackgr[CRABS]; /* flag to see if crab was on backgr
- */
- };
-
- open()
- {
- register WindowPtr wp;
- register struct DCE *dp;
- register struct storage *sp;
- extern char title[];
- struct windowpeek {
- GrafPort port;
- int windowKind;
- };
- short x, i, dir;
- Rect destrect;
-
- save();
- dp = Dp;
- if (dp->dCtlWindow == NULL) {
- HLock(dp->dCtlStorage = NewHandle((long) sizeof(struct storage)));
- sp = SP;
- /* create an invisible window */
- dp->dCtlWindow =
- wp = NewWindow(NULL, &wind_rect, title, FALSE, plainDBox, -1L, FALSE,
- NULL);
- ((struct windowpeek *)wp)->windowKind = dp->dCtlRefNum;
- /* allocate space for new crabport */
- &sp->crabport->device = sp->portspace;
- OpenPort(sp->crabport);
- /* set the 4 crab bitmaps */
- for(i = 0; i < 4; i++){
- sp->crabmap[i].bounds.top = 0;
- sp->crabmap[i].bounds.left = 0;
- sp->crabmap[i].bounds.bottom = 8;
- sp->crabmap[i].bounds.right = 8;
- sp->crabmap[i].rowBytes = 2; /* needs to be even (to fit on a word)
- */
- sp->crabmap[i].baseAddr = &sp->crabspace[i][0];
- }
- StuffHex(sp->crabmap[0].baseAddr, "\P910008007E004200810081004200BD00");
- StuffHex(sp->crabmap[1].baseAddr, "\PBD0042008100810042007E0010008900");
- StuffHex(sp->crabmap[2].baseAddr, "\PB1004C0084008500860084004C00B100");
- StuffHex(sp->crabmap[3].baseAddr, "\P8D00320021006100A100210032008D00");
- /* gray pattern */
- StuffHex(sp->gray, "\PAA55AA55AA55AA55");
- /* set the start positions of the crabs and draw them */
- x = 0;
- dir = 1;
- for (i = 0; i < CRABS; i++){
- sp->newdest[i][0] = x;
- sp->newdest[i][1] = 0;
- x += BASE1/CRABS;
-
- destrect.left = sp->newdest[i][0];
- destrect.top = sp->newdest[i][1];
- destrect.right = sp->newdest[i][0] + 8;
- destrect.bottom = sp->newdest[i][1] + 8;
- CopyBits(&sp->crabmap[dir], &sp->crabport->portBits,
- &sp->crabmap[dir].bounds, &destrect,
- srcCopy, NULL);
- sp->olddir[i] = dir;
- sp->oldbackgr[i] = FALSE;
- sp->olddest[i][0] = sp->newdest[i][0];
- sp->olddest[i][1] = sp->newdest[i][1];
- }
- /* set the background pattern to gray */
- BackPat(sp->gray);
-
- HUnlock(dp->dCtlStorage);
- }
- restore();
- return(0);
- }
-
-
- close()
- {
- register struct DCE *dp;
-
- save();
- dp = Dp;
- /* get rid of the allocated space for the window and crabs */
- DisposeWindow(dp->dCtlWindow);
- dp->dCtlWindow = NULL;
- DisposHandle(dp->dCtlStorage);
- restore();
- return(0);
- }
-
-
- nop()
- {
- return(0);
- }
-
-
-
-
- control()
- {
- register struct DCE *dp;
- register struct storage *sp;
- short x, y, i, j, dir;
- Rect grayrect, destrect;
- Boolean backgr;
-
- save();
- dp = Dp;
- HLock(dp->dCtlStorage);
- sp = SP;
- switch (Pbp->u.cp.csCode) {
- case accRun: /* time to move the crabs */
- SetPort(sp->crabport);
- for (i = 0; i < CRABS; i++) {
- if (!sp->oldbackgr[i]) {
- /* if crab was not on bakcgr, determine complete
- * new x and y velocities */
- sp->xvel[i] = rand(-5, 5);
- sp->yvel[i] = rand(-5, 5);
- } else {
- /* if crab was on backgr, increase or decrease the
- * x and y velocities only slightly */
- if (sp->xvel[i] >= MAXVEL)
- sp->xvel[i] += rand(-1, 0);
- else if (sp->xvel[i] <= -MAXVEL)
- sp->xvel[i] += rand(0, 1);
- else
- sp->xvel[i] += rand(-1,1);
-
- if (sp->yvel[i] >= MAXVEL)
- sp->yvel[i] += rand(-1, 0);
- else if (sp->yvel[i] <= -MAXVEL)
- sp->yvel[i] += rand(0, 1);
- else
- sp->yvel[i] += rand(-1 ,1);
- }
- /* update the crab position */
- sp->newdest[i][0] += sp->xvel[i];
- sp->newdest[i][1] += sp->yvel[i];
- /* make sure to remain within screen boundaries */
- while ((sp->newdest[i][0] < 0) || (sp->newdest[i][0] > BASE1 - 8) ||
- (sp->newdest[i][1] < 0) || (sp->newdest[i][1] > BASE2 - 8)) {
- sp->newdest[i][0] -= sp->xvel[i];
- sp->newdest[i][1] -= sp->yvel[i];
- sp->xvel[i] = rand(-5, 5);
- sp->yvel[i] = rand(-5, 5);
- sp->newdest[i][0] += sp->xvel[i];
- sp->newdest[i][1] += sp->yvel[i];
- }
- /* calculate new direction of crab */
- if (abs(sp->yvel[i]) >= abs(sp->xvel[i]))
- if (sp->yvel[i] <= 0)
- dir = 0;
- else
- dir = 1;
- else
- if (sp->xvel[i] >= 0)
- dir = 2;
- else
- dir = 3;
- /* erase the crab from the previous position, by drawing
- * it over with the gray background */
- grayrect.left = sp->olddest[i][0];
- grayrect.top = sp->olddest[i][1];
- grayrect.right = sp->olddest[i][0] + 8;
- grayrect.bottom = sp->olddest[i][1] + 8;
- EraseRect(&grayrect);
-
- /* determine if the new position does occupy a
- * non gray site */
- j = 0;
- backgr = TRUE;
- x = sp->newdest[i][0];
- if (sp->xvel[i] > 0)
- y = sp->newdest[i][1] + 7; /* scan only bottom line */
- else /* of new crab position */
- y = sp->newdest[i][1]; /* or only top line */
- for (;x <= sp->newdest[i][0] + 7; x++)
- if (GetPixel(x, y)) j++;
- if (j != 4) backgr = FALSE;
- sp->oldbackgr[i] = backgr;
-
- if (!backgr) {
- /* if the site is not gray, make it gray and redraw
- * the crab in the previous position */
- grayrect.left = sp->newdest[i][0];
- grayrect.top = sp->newdest[i][1];
- grayrect.right = sp->newdest[i][0] + 8;
- grayrect.bottom = sp->newdest[i][1] + 8;
- EraseRect(&grayrect);
- destrect.left = sp->olddest[i][0];
- destrect.top = sp->olddest[i][1];
- destrect.right = sp->olddest[i][0] + 8;
- destrect.bottom = sp->olddest[i][1] + 8;
- dir = sp->olddir[i];
- CopyBits(&sp->crabmap[dir], &sp->crabport->portBits,
- &sp->crabmap[dir].bounds, &destrect,
- srcCopy, NULL);
- sp->newdest[i][0] = sp->olddest[i][0];
- sp->newdest[i][1] = sp->olddest[i][1];
- } else {
- /* if the site is gray, draw the crab in the new
- * position */
- destrect.left = sp->newdest[i][0];
- destrect.top = sp->newdest[i][1];
- destrect.right = sp->newdest[i][0] + 8;
- destrect.bottom = sp->newdest[i][1] + 8;
- CopyBits(&sp->crabmap[dir], &sp->crabport->portBits,
- &sp->crabmap[dir].bounds, &destrect,
- srcCopy, NULL);
- sp->olddest[i][0] = sp->newdest[i][0];
- sp->olddest[i][1] = sp->newdest[i][1];
- sp->olddir[i] = dir;
- }
- }
- break; /* end case */
- }
- HUnlock(dp->dCtlStorage);
- restore();
- return(0);
- }
-
-
- /* Return random number uniformly distributed on [min,max].
- * Note that Random() delivers a value on [-32768,32767]. */
- rand(min, max)
- int min, max;
- {
- float ran;
-
- ran = (max - min + 1.0)*(float)abs(Random())/32768.0 + min;
- return((ran < 0) ? --ran : ran);
- }
-
-
- /* Return absolute value of an integer */
- abs(n)
- int n;
- {
- return((n > 0) ? n : -n);
- }
-